package com.general.framework.core.lang;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;

import java.lang.reflect.Field;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author leejean
 * @ClassName: Beans
 * @Description: 基于cglib的bean快速copy工具
 * 几种copy工具对比来自网上：https://blog.csdn.net/l848168/article/details/84937387
 * @date 2019年09月10 10:53:32
 */
@Slf4j
public class Beans {

    // CGLib 缓存已移除，使用 Spring BeanUtils 替代

    /**
     * 拷贝
     *
     * @param source
     * @param targetClass
     * @param <T>
     * @return
     */
    public static <T> T copy(Object source, Class<T> targetClass) {
        if (Objects.isNull(source)) {
            return null;
        }
        return baseMapper(source, targetClass);
    }

    /**
     * 复制属性
     *
     * @param source
     * @param target
     * @param <T>
     * @return
     */
    public static <T> T copyProperties(Object source, T target) {
        if (Objects.isNull(source) || Objects.isNull(target)) {
            return null;
        }
        BeanUtils.copyProperties(source, target);
        return target;
    }


    /**
     * 转换为map
     *
     * @param source
     * @return
     */
    public static Map<String, Object> toMap(Object source) {
        if (Objects.isNull(source)) {
            return new HashMap<>(1);
        }
        
        Map<String, Object> result = new HashMap<>();
        try {
            Field[] fields = source.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                Object fieldValue = field.get(source);
                result.put(fieldName, fieldValue);
            }
        } catch (Exception e) {
            log.error("转换对象为Map时发生异常", e);
        }
        return result;
    }

    /**
     * list copy，跟bean属性相同，不过是copy整个集合而已
     *
     * @param sourceList  源集合
     * @param targetClass 目标类型
     * @param <T>
     * @return
     */
    public static <T> List<T> copyList(List<?> sourceList, Class<T> targetClass) {
        if (sourceList == null || sourceList.isEmpty()) {
            return Collections.emptyList();
        }
        return sourceList.stream().map(e -> baseMapper(e, targetClass)).collect(Collectors.toList());
    }

    /**
     * 基本复制
     */
    private static <T> T baseMapper(Object source, Class<T> target) {
        try {
            final T instance = target.getDeclaredConstructor().newInstance();
            BeanUtils.copyProperties(source, instance);
            return instance;
        } catch (Exception e) {
            log.error("mapper 创建对象异常", e);
        }
        return null;
    }

    // CGLib 缓存方法已移除，使用 Spring BeanUtils 无需缓存

}
